home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEMP / GNU / bison / Debugging < prev    next >
Text File  |  1995-06-28  |  4KB  |  87 lines

  1. Debugging
  2. Previous: <Context Dependency=>ContextDep> * Next: <Invocation=>Invocation> * Up: <Top=>!Root>
  3.  
  4. #Wrap on
  5. {fH2}Debugging Your Parser{f}
  6.  
  7. If a Bison grammar compiles properly but doesn't do what you want when it
  8. runs, the {fCode}yydebug{f} parser-trace feature can help you figure out why.
  9.  
  10. To enable compilation of trace facilities, you must define the macro
  11. {fCode}YYDEBUG{f} when you compile the parser.  You could use
  12. {fEmphasis}-DYYDEBUG=1{f} as a compiler option or you could put {fEmphasis}\#define
  13. YYDEBUG 1{f} in the C declarations section of the grammar file 
  14. (\*Note <C Declarations=>CDeclarati>: The C Declarations Section).  Alternatively, use the {fEmphasis}-t{f} option when
  15. you run Bison (\*Note <Invocation=>Invocation>: Invoking Bison).  We always define {fCode}YYDEBUG{f} so that
  16. debugging is always possible.
  17.  
  18. The trace facility uses {fCode}stderr{f}, so you must add {fCode}\#include
  19. <stdio.h>{f} to the C declarations section unless it is already there.
  20.  
  21. Once you have compiled the program with trace facilities, the way to
  22. request a trace is to store a nonzero value in the variable {fCode}yydebug{f}.
  23. You can do this by making the C code do it (in {fCode}main{f}, perhaps), or
  24. you can alter the value with a C debugger.
  25.  
  26. Each step taken by the parser when {fCode}yydebug{f} is nonzero produces a
  27. line or two of trace information, written on {fCode}stderr{f}.  The trace
  28. messages tell you these things:
  29.  
  30. #Indent +4
  31.  
  32.  • Each time the parser calls {fCode}yylex{f}, what kind of token was read.
  33.  
  34.  
  35.  • Each time a token is shifted, the depth and complete contents of the
  36. state stack (\*Note <Parser States=>ParserStat>).
  37.  
  38.  
  39.  • Each time a rule is reduced, which rule it is, and the complete contents
  40. of the state stack afterward.
  41.  
  42. #Indent
  43.  
  44. To make sense of this information, it helps to refer to the listing file
  45. produced by the Bison {fEmphasis}-v{f} option (\*Note <Invocation=>Invocation>: Invoking Bison).  This file
  46. shows the meaning of each state in terms of positions in various rules, and
  47. also what each state will do with each possible input token.  As you read
  48. the successive trace messages, you can see that the parser is functioning
  49. according to its specification in the listing file.  Eventually you will
  50. arrive at the place where something undesirable happens, and you will see
  51. which parts of the grammar are to blame.
  52.  
  53. The parser file is a C program and you can use C debuggers on it, but it's
  54. not easy to interpret what it is doing.  The parser function is a
  55. finite-state machine interpreter, and aside from the actions it executes
  56. the same code over and over.  Only the values of variables show where in
  57. the grammar it is working.
  58.  
  59. The debugging information normally gives the token type of each token
  60. read, but not its semantic value.  You can optionally define a macro
  61. named {fCode}YYPRINT{f} to provide a way to print the value.  If you define
  62. {fCode}YYPRINT{f}, it should take three arguments.  The parser will pass a
  63. standard I\/O stream, the numeric code for the token type, and the token
  64. value (from {fCode}yylval{f}).
  65.  
  66. Here is an example of {fCode}YYPRINT{f} suitable for the multi-function
  67. calculator (\*Note <Mfcalc Decl=>MfcalcDecm>: Declarations for {fCode}mfcalc{f}):
  68.  
  69. #Wrap off
  70. #fCode
  71. \#define YYPRINT(file, type, value)   yyprint (file, type, value)
  72.  
  73. static void
  74. yyprint (file, type, value)
  75.      FILE \*file;
  76.      int type;
  77.      YYSTYPE value;
  78. \{
  79.   if (type == VAR)
  80.     fprintf (file, " %s", value.tptr->name);
  81.   else if (type == NUM)
  82.     fprintf (file, " %d", value.val);
  83. \}
  84. #f
  85. #Wrap on
  86.  
  87.